PreLab 11

Multiprocessing
Due in class on Wednesday, December 2

This week we will write programs that create multiple processes that run simultaneously.

Part 1 - Creating a Process

This week, we will be working with the python multiprocessing module, which allows us to run multiple processes at the same time. To create a new process, you will first create a function that does whatever you want your process to do, and then call
p = Process(target=function_name, args=(yourargs,))
to create the process, and p.start() to run the process. Note that process uses named arguments: you will always need to put "target=" before the function name, and "args=" before the arguments. Also note that the arguments are passed in as a tuple.

1.Here is a Python function::

def ad(string):
        print(string)
        print( "brought to you courtesy of process %d" %current_process().pid)

For example, if I call ad("Python!) it prints

Python!
brought to you courtesy of process 7544

Write a main() function that starts up 10 processes to execute this function on whatever string you like. You might want to use a loop here, or alternatively you could use a process Pool that creates 10 processes that are mapped to a function.

 

Synchronization and Locks

It frequently makes sense for processes to be able to access the same variables, so they can work together. However, this can be very dangerous, as we will get incorrect results if two or more processes modify the same variable at the same time. To avoid this, we will use something called a Lock, which will only allow one process at a time to access a variable. Locks are very simple. We create one with


         L = Lock()


A process can lock L with


         L.acquire()

The process that has locked L can unlock it with

         L.release()

2. Here is code for a program that uses 10 processes to count from 1 to 100. The variable i is a 'RawValue' that can be passed to different processes. i.value is the value i represents.

from multiprocessing import *
import time

def Counter(i, max):
         while i.value < max:
                  if i.value < max:
                           i.value = i.value + 1
                           print( "Proces %d set i=%d"%(current_process().pid, i.value))
                           time.sleep(0.5)

def main():
         i = RawValue( "i", 0)
         max = 100
         for x in range(10):
                  p = Process(target=Counter, args = (i, max))
                  p.start()

This counts like a crazy person. Here is a portion of its output from one run:

Process 1265 set i=92
Process 3454 set i=94
Process 1265 set i=94
Process 1123 set i=95
Process 3454 set i=95
Process 1265 set i=99
Process 3333 set i=100
Process 1123 set i=100
....

Explain this. Why do several processes all set i to 94, while none of them set it to 96 or 97?